﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Qreed.Windows.ComponentModel;
using System.IO;
using System.Reflection;
using System.Diagnostics;

namespace GotLyrics
{
    public partial class GeneralPropertiesControl
    {
        private GotLyricsMainForm _mainForm;
        /// <summary>
        /// Gets or sets the main form.
        /// </summary>
        /// <value>The main form.</value>
        internal GotLyricsMainForm MainForm
        {
            get { return _mainForm; }
            set { _mainForm = value; }
        }

        /// <summary>
        /// Occurs when a value of a property has changed.
        /// </summary>
       /* public event PropertyValueChangedEventHandler PropertyValueChanged
        {
            add { propertyGrid.PropertyValueChanged += value; }
            remove { propertyGrid.PropertyValueChanged -= value; }
        }*/

        private AudioFileContext[] _selection;

        public GeneralPropertiesControl()
        {
            InitializeComponent();
            
            // Hook the double click event
            foreach (Control c in propertyGrid.Controls)
            {
                if (c.GetType().ToString() == "System.Windows.Forms.PropertyGridInternal.PropertyGridView")
                {
                    c.DoubleClick += new EventHandler(propertyGrid_DoubleClick);

                }
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            bool ret = base.ProcessCmdKey(ref msg, keyData);

            if (keyData == Keys.Enter) // Select the grid item
            {
                SendKeys.Send("{DOWN}{TAB}");
            }

            return ret;
        }

        public void SetSelection(AudioFileContext[] selection)
        {
            _selection = selection;

            if (selection != null && _selection.Length > 0)
            {
                List<PropertyBag> bags = new List<PropertyBag>();

                foreach (AudioFileContext context in selection)
                {
                    PropertyBag bag = new PropertyBag();

                    bag.Items.Add(new PropertyBagItem("Filename", "Filename", context.Filename, context.Filename, "File Information", "The filename of the selected audio file.", true, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("Size", "Size", context.Tags.Size, context.Tags.Size, "File Information", "The size of the file in bytes.", true, true, typeof(long?)));

                    bag.Items.Add(new PropertyBagItem("Artist", "Song Artist", context.Tags.Artist, context.Tags.Artist, "Track Information", "The name of the artist.", false, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("UnsyncedLyrics", "Song Lyrics", context.Tags.UnsyncedLyrics, context.Tags.UnsyncedLyrics, "Track Information", "The lyrics of this song.", false, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("Title", "Song Title", context.Tags.Title, context.Tags.Title, "Track Information", "The title of the song.", false, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("TrackNum", "Track #", context.Tags.TrackNum, context.Tags.TrackNum, "Track Information", "The track number of this song on this album.", false, true, typeof(short?)));
                    bag.Items.Add(new PropertyBagItem("Comments", "Comments", context.Tags.Comments, context.Tags.Comments, "Track Information", "User comments.", false, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("Duration", "Track Duration", context.Tags.Duration, context.Tags.Duration, "Track Information", "The length of the song.", true, true, typeof(TimeSpan)));

                    bag.Items.Add(new PropertyBagItem("Album", "Album Title", context.Tags.Album, context.Tags.Album, "Album Information", "The name of the album.", false, true, typeof(string)));
                    bag.Items.Add(new PropertyBagItem("Year", "Year Released", context.Tags.Year, context.Tags.Year, "Album Information", "The year this album has been released.", false, true, typeof(short?)));

                    foreach (PropertyBagItem item in bag.Items)
                        item.Tag = context;

                    // Set the right editor for the lyrics
                    bag.Items["UnsyncedLyrics"].TypeEditor = new LyricsUITypeEditor(this);
                    bag.Items["UnsyncedLyrics"].IsReadOnly = true;

                    bags.Add(bag);
                }

                PropertyBagMergeOptions mergeOptions = PropertyBagMergeOptions.AlwaysCreateExpandable |
                                                       PropertyBagMergeOptions.IncludeUniqueField;

                PropertyBag mergedBag = PropertyBag.Merge("Filename", bags.ToArray(), mergeOptions);

                // Cheap trick to make a nicer displayname for expanded items

                foreach (PropertyBagItem item in mergedBag.Items)
                {
                    if (item is PropertyBagExpandableItem)
                    {
                        foreach (PropertyBagItem subItem in ((PropertyBagExpandableItem)item).Items)
                            subItem.DisplayName = Path.GetFileName(subItem.DisplayName);
                    }
                }

                propertyGrid.SelectedObject = mergedBag;
                mergedBag.SetValue += new EventHandler<PropertyBagEventArgs>(PropertyBagSetValue);
            }
            else
            {
                propertyGrid.SelectedObject = null;
            }
        }

        void PropertyBagSetValue(object sender, PropertyBagEventArgs e)
        {
            Type t = typeof(Tags);
            PropertyInfo pi = t.GetProperty(e.Item.Name);

            if(pi == null)
                throw (new ApplicationException("Property not found: " + e.Item.Name));

            AudioFileContext c = (AudioFileContext)e.Item.Tag;

            pi.SetValue(c.Tags, e.Value, null);
            c.IsModified = true;
            c.ReflectListViewItem();
        }

        private void propertyGrid_DoubleClick(object sender, EventArgs e)
        {
            
        }

        private void propertyGrid_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
        {
            //Debug.WriteLine(e.NewSelection.);    
        } 
    }
}
